﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;

// 版本检测结束
public class CheckVersion
{
    string LocalConfigPath;
    string LocalPath;

    public delegate void CheckVersionEnd();

    CheckVersionEnd mCheckVersionEnd;

	// Use this for initialization
    public void Start(CheckVersionEnd f)
    {
        mCheckVersionEnd = f;

#if UNITY_EDITOR
        LocalConfigPath = "file://" + ResourcesPath.LocalConfigPath;
        LocalPath = "file://" + ResourcesPath.LocalPath;
#endif
#if (UNITY_ANDROID || UNITY_IPHONE) && (!UNITY_EDITOR)
        LocalConfigPath = ResourcesPath.LocalConfigPath;
        LocalPath = ResourcesPath.LocalPath;
#endif
        // 加载下本地的版本文件
        ResourceDown.Instance.Load(LocalConfigPath + "version.txt", loadLocalVersionEnd);
	}

    // 服务器的文件数据
    Dictionary<string, byte[]> ServerFileData = new Dictionary<string, byte[]>();

    System.Version version; // 版本号
    void loadLocalVersionEnd(WWW www, object p)
    {
        if (www.error != null)
        {
            // 有错误，可能本地没有版本文件，需要更新所有的资源
            version = null;
        }
        else
        {
            version = new System.Version(www.text);
        }

        Debug.Log(string.Format("version:{0} file:{1}", version, www.url));

        // 去服务器更新下新的版本
        ResourceDown.Instance.Load(ResourcesPath.RemoteConfigPath + "version.txt", loadServerVersionEnd);
    }

    void loadServerVersionEnd(WWW www, object p)
    {
        if (www.error != null)
        {
            Debug.Log(string.Format("服务器版本下载错误!{0} url:{1}", www.error, www.url));
            return; // 服务器版本错误
        }

        System.Version serverVersion = new System.Version(www.text);
        if (serverVersion == version)
        {
            // 版本一至，那么，不需要更新
            Debug.Log("版本一至不需要更新!");

            if (mCheckVersionEnd != null)
                mCheckVersionEnd();
        }
        else
        {
            Debug.Log(string.Format("server version:{0} file:{1}", serverVersion, www.url));

            ServerFileData[LocalConfigPath + "version.txt"] = www.bytes;

            // 版本不一至，需要更新至最新版本
            // 加载下本地的md5文件列表
            ResourceDown.Instance.Load("file://" + LocalConfigPath + "FilesMD5.csv", LoadLocalMd5FileEnd);
        }
    }

    Dictionary<string, string> MD5FileList = new Dictionary<string, string>();
    void LoadLocalMd5FileEnd(WWW www, object p)
    {
        if (www.error != null)
        {
            // 没有找到本地文件，那么
            Debug.Log(string.Format("没有查找到本地的MD5文件!{0}! url:{1}", www.error, www.url));
        }
        else
        {
            Debug.Log(string.Format("加载本地MD5文件成功!url:{0}", www.url));

            // 找着了本地文件
            Csv.CsvReader csv = new Csv.CsvReader();
            csv.Load(www.text, ',');
            for (int i = 0; i < csv.getYCount(); ++i)
                MD5FileList.Add(csv.getStr(i, 0), csv.getStr(i, 1));
        }

        // 再去下载下服务器的md5文件列表
        ResourceDown.Instance.Load(ResourcesPath.RemoteConfigPath + "FilesMD5.csv", LoadServerMd5FileEnd);
    }

    List<string[]> UpdateFileList = new List<string[]>(); // 等更新的文件列表
    void LoadServerMd5FileEnd(WWW www, object p)
    {
        if (www.error != null)
        {
            // 没有找到服务器的md5文件，那么
            Debug.Log(string.Format("没有查找到服务器的MD5文件!{0}", www.error));
        }
        else
        {
            Debug.Log(string.Format("加载服务器MD5文件成功!url:{0} text:{1}", www.url, www.text));

            ServerFileData[LocalConfigPath + "FilesMD5.csv"] = www.bytes;

            Dictionary<string, string> ServerMd5List = new Dictionary<string, string>();
            Csv.CsvReader csv = new Csv.CsvReader();
            csv.Load(www.text, ',');
            string file;
            for (int i = 0; i < csv.getYCount(); ++i)
            {
                if (!string.IsNullOrEmpty((file = csv.getStr(i, 0))))
                {
                    if (!ServerFileData.ContainsKey(file))
                    {
                        ServerMd5List.Add(file, csv.getStr(i, 1));
                        Debug.Log(string.Format("update file:{0}!", file));
                    }
                    else
                        Debug.Log(string.Format("file:{0} rep!", file));
                }
            }

            // 开始资源的更新,先删除用无的文件
            foreach (KeyValuePair<string, string> itor in MD5FileList)
            {
                if (!ServerMd5List.ContainsKey(itor.Key))
                {
                    // 可以删除本地的文件
                    File.Delete(LocalPath + itor.Key);
                }
            }

            // 下载需要更新的资源
            string md5 = "";
            foreach (KeyValuePair<string, string> itor in ServerMd5List)
            {
                if ((!MD5FileList.TryGetValue(itor.Key, out md5)) || itor.Value != md5)
                {
                    UpdateFileList.Add(new string[2] { itor.Key, itor.Value });
                }
            }

            // 开始向服务器请求资源下载
            if (UpdateFileList.Count == 0)
            {
                WriteFileToLocal();
            }
            else
            {
                current = 0;
                Debug.Log(string.Format("下中{0}:{1}", current, UpdateFileList[0][0]));
                ResourceDown.Instance.Load(ResourcesPath.RemotePath + UpdateFileList[0][0], LoadServerFileEnd);
            }
        }
    }

    void LoadServerFileEnd(WWW www, object p)
    {
        current++;
        if (www.error != null)
        {
            Debug.LogError(string.Format("下载服务器资源失败!路径:{0} error:{1}", www.url, www.error));
        }
        else
        {
            string[] files = UpdateFileList[current-1];
            ServerFileData.Add(LocalPath + files[0], www.bytes);
            Debug.Log(string.Format("下载服务器资源成功!路径:{0}", www.url));
        }

        if (current == UpdateFileList.Count)
        {
            Debug.Log("资源下载完成!");
            WriteFileToLocal();
        }
        else
        {
            Debug.Log(string.Format("下中{0}:{1}", current, UpdateFileList[current][0]));
            ResourceDown.Instance.Load(ResourcesPath.RemotePath + UpdateFileList[current][0], LoadServerFileEnd);
        }
    }

    int current = 0;

    // 定入文件到本地
    void WriteFileToLocal()
    {
        foreach (KeyValuePair<string, byte[]> itor in ServerFileData)
        {
            string dir = itor.Key.Substring(0, Mathf.Max(itor.Key.LastIndexOf('/'), itor.Key.LastIndexOf('\\')));
            if (dir.LastIndexOf("file://") == 0)
            {
                dir = dir.Substring(7);
                Directory.CreateDirectory(dir);
                dir = itor.Key.Substring(7);
            }
            else
            {
                Directory.CreateDirectory(dir);
                dir = itor.Key;
            }

            FileStream fileStream = new FileStream(dir, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write);
            fileStream.Write(itor.Value, 0, itor.Value.Length);
            fileStream.Flush();
            fileStream.Close();

            Debug.Log(string.Format("更新资源:{0}", itor.Key));
        }

        if (mCheckVersionEnd != null)
            mCheckVersionEnd();
    }
}
